package com.pangu.ui.browser;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.HeaderViewListAdapter;
import android.widget.ListView;

import com.pangu.AMApplication;
import com.pangu.task.AServiceWrapper;
import com.pangu.task.IResultReceiver;
import com.pangu.task.mark.ATaskMark;
import com.pangu.ui.R;
import com.pangu.ui.widget.GridViewWithHeaderAndFooter;

import java.util.HashMap;
import java.util.Map;

/**
 * 列表类项加载的父类,提供加载提示。下拉和超时自刷新功能， 外部使用时不同taskMark对应不同的LoadableList以避免视图状态的干扰。
 * <p/>
 * Created by cxlin
 */
public abstract class LoadableList<A extends AMApplication> extends LoadableView<A> implements IResultReceiver,
		OnItemClickListener, AdapterView.OnItemLongClickListener, AbsListView.OnScrollListener {

	public static final String TAG = LoadableList.class.getSimpleName();

	// 列表视图
	protected AdapterView adapterView;

	private Map<Integer, Integer> heights = new HashMap<>();

	private int lastCurrentScrollY = 0;

	private int mToolBarAutoHideSensitivity = 0;

	private int mToolBarBarAutoHideMinY = 0;

	private int mToolBarAutoHideSignal = 0;

	private boolean mToolBarShown = true;

	private LoadableListScrollListener mListener;

	public LoadableList(Context context) {
		super(context);
	}

	public LoadableList(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	@Override
	protected View createContentView() {
		adapterView = createAdapterView();
		adapterView.setVerticalScrollBarEnabled(false);
		adapterView.setHorizontalScrollBarEnabled(false);
		adapterView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
		adapterView.setOnItemClickListener(this);
		adapterView.setOnItemLongClickListener(this);

		BaseAdapter adapter = createAdapter();
		if (adapterView instanceof ExpandableListView) {
			((ExpandableListView) adapterView).setAdapter((ExpandableListAdapter) adapter);

		} else {
			adapterView.setAdapter(adapter);
		}

		if (adapterView instanceof ListView) {
			mToolBarAutoHideSensitivity = getResources().getDimensionPixelSize(R.dimen.tool_bar_auto_hide_sensitivity);
			mToolBarBarAutoHideMinY = getResources().getDimensionPixelSize(R.dimen.tool_bar_auto_hide_min_y);
			((ListView) adapterView).setOnScrollListener(this);
		}

		return adapterView;
	}

	/**
	 * 创建视图
	 * 
	 * @return
	 */
	protected abstract AdapterView createAdapterView();

	/**
	 * 获取内容视图
	 * 
	 * @return
	 */
	public AdapterView getAdapterView() {
		return adapterView;
	}

	/**
	 * 创建视图对应的Adapter
	 * 
	 * @return
	 */
	protected abstract BaseAdapter createAdapter();

	@Override
	public boolean isLoadDataEmpty() {
		return getDataItemCount() == 0;
	}

	/**
	 * 返回这个列表里总共的条数<br>
	 * 这返回的项的数据没有包括头部和尾部
	 * 
	 * @return
	 */
	public int getDataItemCount() {
		Adapter adapter = getMAdapter();
		if (adapter != null) {
			return adapter.getCount();

		} else {
			return 0;
		}
	}

	/**
	 * 基础适配器
	 * 
	 * @return
	 */
	protected BaseAdapter getMAdapter() {
		if (adapterView != null) {
			Adapter adapter = adapterView.getAdapter();
			if (adapter instanceof HeaderViewListAdapter) {
				return ((BaseAdapter) ((HeaderViewListAdapter) adapter).getWrappedAdapter());

			} else if (adapter instanceof GridViewWithHeaderAndFooter.HeaderViewGridAdapter) {
				return ((BaseAdapter) ((GridViewWithHeaderAndFooter.HeaderViewGridAdapter) adapter).getWrappedAdapter());

			} else {
				return ((BaseAdapter) adapter);
			}

		} else {
			return null;
		}
	}

	@Override
	protected void tryQueryNewItems(int taskType) {
		if (taskType == ATaskMark.TYPE_DEFAULT) {
			tryQueryNewItems(true, taskType);

		} else {
			tryQueryNewItems(false, taskType);
		}
	}

	/**
	 * 尝试获得新的项
	 * 
	 * @param showStatus
	 *            是否显示加载状态还是静默加载
	 * @param taskType
	 */
	protected void tryQueryNewItems(boolean showStatus, int taskType) {
		// 先检查是否还需要加载
		if ((!mTaskMark.isLoadEnd() || taskType == ATaskMark.TYPE_REFRESH)
				&& mTaskMark.getTaskStatus() != ATaskMark.HANDLE_DOING
				&& mTaskMark.getTaskStatus() != ATaskMark.HANDLE_ERROR) {
			// 设置加载类型
			mTaskMark.setTaskType(taskType);
			if (mTaskMark.getDependTask() != null) {
				mTaskMark.getDependTask().setTaskType(taskType);
			}
			if (isAutoLoad()) {
				handleLoadNewItems(mTaskMark);

			} else {
				mTaskMark.setTaskStatus(ATaskMark.HANDLE_WAIT);
			}

		} else if (mTaskMark.getTaskStatus() == ATaskMark.HANDLE_DOING) {
			AServiceWrapper.forceTakeoverTask(this, mTaskMark);
		}

		if (showStatus || mTaskMark.getTaskStatus() != ATaskMark.HANDLE_DOING) {
			updateViewStatus(mTaskMark);
		}
	}

	/**
	 * 子类处理具体项的加载
	 * 
	 * @param taskMark
	 */
	protected abstract void handleLoadNewItems(ATaskMark taskMark);

	public void setLoadableListScrollListener(LoadableListScrollListener listener) {
		this.mListener = listener;
	}

	@Override
	public void notifyDataSetChanged() {
		super.notifyDataSetChanged();

		BaseAdapter adapter = getMAdapter();
		if (adapter != null) {
			adapter.notifyDataSetChanged();
		}
	}

	public void scrollUp() {
		if (adapterView != null) {
			adapterView.setSelection(0);
		}
	}

	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {

	}

	@Override
	public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
		// Get the first visible item's view.
		View firstVisibleItemView = view.getChildAt(0);
		if (firstVisibleItemView == null) {
			return;
		}

		// Save the height of the visible item.
		heights.put(firstVisibleItem, firstVisibleItemView.getHeight());

		// Calculate the height of all previous (hidden) items.
		int previousItemsHeight = 0;
		for (int i = 0; i < firstVisibleItem; i++) {
			previousItemsHeight += heights.get(i) != null ? heights.get(i) : 0;
		}

		int currentScrollY = previousItemsHeight - firstVisibleItemView.getTop()
				+ view.getPaddingTop();

		onMainContentScrolled(currentScrollY, currentScrollY - lastCurrentScrollY);

		lastCurrentScrollY = currentScrollY;
	}

	private void onMainContentScrolled(int currentY, int deltaY) {
		if (deltaY > mToolBarAutoHideSensitivity) {
			deltaY = mToolBarAutoHideSensitivity;
		} else if (deltaY < -mToolBarAutoHideSensitivity) {
			deltaY = -mToolBarAutoHideSensitivity;
		}

		if (Math.signum(deltaY) * Math.signum(mToolBarAutoHideSignal) < 0) {
			// deltaY is a motion opposite to the accumulated signal, so reset signal
			mToolBarAutoHideSignal = deltaY;
		} else {
			// add to accumulated signal
			mToolBarAutoHideSignal += deltaY;
		}

		boolean shouldShow = currentY < mToolBarBarAutoHideMinY ||
				(mToolBarAutoHideSignal <= -mToolBarAutoHideSensitivity);

		if (shouldShow == mToolBarShown) {
			return;
		}

		mToolBarShown = shouldShow;
		onToolBarAutoShowOrHide(shouldShow);
	}

	private void onToolBarAutoShowOrHide(boolean shouldShow) {
		if (mListener != null) {
			if (shouldShow) {
				mListener.onScrollUp();
			} else {
				mListener.onScrollDown();
			}
		}
	}

	public interface LoadableListScrollListener {
		void onScrollUp();
		void onScrollDown();
	}
}
